/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ssm.changeunit.util;

import java.io.*;
import java.util.*;

/**
 *
 * @author 시리우스
 */
public class FileUtil {

    public static String getRelativePath(File file, File relativeTo) throws IOException {
        /*
         * windows seems in some cases not to stop getParent() at 'c:\', which I
         * considered to be root. For that reason I had to tweak in the
         * following to 'ugly' lines:
         */
        file = new File(file + File.separator + "89243jmsjigs45u9w43545lkhj7").getParentFile();
        relativeTo = new File(relativeTo + File.separator + "984mvcxbsfgqoykj30487df556").getParentFile();

        File origFile = file;
        File origRelativeTo = relativeTo;
        ArrayList<File> filePathStack = new ArrayList<File>();
        ArrayList<File> relativeToPathStack = new ArrayList<File>();
        // build the path stack info to compare it afterwards
        file = file.getCanonicalFile();
        while (file != null) {
            filePathStack.add(0, file);
            file = file.getParentFile();
        }
        relativeTo = relativeTo.getCanonicalFile();
        while (relativeTo != null) {
            relativeToPathStack.add(0, relativeTo);
            relativeTo = relativeTo.getParentFile();
        }
        // compare as long it goes
        int count = 0;
        file = filePathStack.get(count);
        relativeTo = relativeToPathStack.get(count);
        while ((count < filePathStack.size() - 1) && (count < relativeToPathStack.size() - 1) && file.equals(relativeTo)) {
            count++;
            file = filePathStack.get(count);
            relativeTo = relativeToPathStack.get(count);
        }
        if (file.equals(relativeTo)) {
            count++;
        // up as far as necessary
        }
        StringBuffer relString = new StringBuffer();
        for (int i = count; i < relativeToPathStack.size(); i++) {
            relString.append(".." + File.separator);
        }
        // now back down to the file
        for (int i = count; i < filePathStack.size() - 1; i++) {
            relString.append(filePathStack.get(i).getName() + File.separator);
        }
        relString.append(filePathStack.get(filePathStack.size() - 1).getName());
        // just to test
        File relFile = new File(origRelativeTo.getAbsolutePath() + File.separator + relString.toString());
        if (!relFile.getCanonicalFile().equals(origFile.getCanonicalFile())) {
            throw new IOException("Failed to find relative path.");
        }
        return relString.toString();
    }

    public static String readFromFile(String fileName) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(fileName));
        StringBuilder stringBuilder = new StringBuilder();
        String in;

        while ((in = br.readLine()) != null) {
            stringBuilder.append(in + "\n");
        }
        return stringBuilder.toString();
    }

    public static byte[] readFromFileToByte(String _filePath) throws IOException {
        if (!hasFile(_filePath)) {
            throw new FileNotFoundException("파일을 찾을 수 없습니다. File name: " + _filePath);
        }
        File file = new File(_filePath);

        FileInputStream fileInputStream = new FileInputStream(file);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024];
        int count = 0;

        while ((count = fileInputStream.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, count);
        }
        byte[] result = byteArrayOutputStream.toByteArray();

        byteArrayOutputStream.flush();
        byteArrayOutputStream.close();
        fileInputStream.close();

        return result;
    }

    /**
     * 데이터를 파일에 저장한다.
     * 
     * @param _directoryPath	디렉토리 경로
     * @param _fileName			파일 이름
     * @param _fileData			파일 데이터
     * @throws IOException		예기치 못한 경우로 인해 파일을 저장하지 못한 경우 발생
     */
    public static void saveDataToFile(String _filePath, String _fileData) throws IOException {
        try {
            File f = new File(_filePath);

            // 디렉토리가 존재하지 않으면 디렉토리 생성
            if (!f.getParentFile().exists()) {
                f.getParentFile().mkdirs();
            }
            f.createNewFile();

            FileOutputStream fileOutputStream = new FileOutputStream(f);

            fileOutputStream.write(_fileData.getBytes());
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e) {
            throw new IOException("파일에 쓸수 없습니다. File name: " + _filePath);
        }
    }

    /**
     * 데이터를 파일에 저장한다.
     * 
     * @param _directoryPath	디렉토리 경로
     * @param _fileName			파일 이름
     * @param _fileData			파일 데이터
     * @throws IOException		예기치 못한 경우로 인해 파일을 저장하지 못한 경우 발생
     */
    public static void saveByteDataToFile(String _filePath, byte[] _fileData) throws IOException {
        try {
            File f = new File(_filePath);

            // 디렉토리가 존재하지 않으면 디렉토리 생성
            if (!f.getParentFile().exists()) {
                f.getParentFile().mkdirs();
            }
            f.createNewFile();

            FileOutputStream fileOutputStream = new FileOutputStream(f);

            fileOutputStream.write(_fileData);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e) {
            throw new IOException("파일에 쓸수 없습니다. File name: " + _filePath);
        }
    }

    /**
     * 파일이 존재하는지 검사
     * 
     * @param _filePath		파일의 경로
     * @return				파일의 존재 여부
     */
    public static boolean hasFile(String _filePath) {
        File file = new File(_filePath);

        return file.exists();
    }

    /**
     * 디렉토리가 존재하는지 검사
     * 
     * @param _directoryPath	디렉토리 경로
     * @return					디렉토리의 존재 여부
     */
    public static boolean hasDirectory(String _directoryPath) {
        File directory = new File(_directoryPath);

        return directory.exists();
    }

    /**
     * 디렉토리를 생성한다.
     * 만약 존재할 경우 생성하지 않는다.
     * 
     * @param _directoryPath	디렉토리 경로
     */
    public static boolean directoryCreateOrNone(String _directoryPath) {
        if (!hasDirectory(_directoryPath)) {
            return new File(_directoryPath).mkdirs();
        }
        return true;
    }

    /**
     * 파일 구분자를 붙인다.
     * 만약 파일 구분자가 마지막에 존재할 경우 붙이지 않는다.
     * 
     * @param _directoryPath	파일 구분자를 붙일 디렉토리 경로
     * @return
     */
    public static String fileSeparatorAddOrNone(String _directoryPath) {
        if (!(_directoryPath.endsWith("/") || _directoryPath.endsWith("\\"))) {
            _directoryPath += File.separator;
        }
        return _directoryPath;
    }

    public static boolean isAbsolutePath(String _directoryPath) {
        File file = new File(_directoryPath);

        return file.isAbsolute();
    }

    public static boolean delete(String _filePath) {
        File file = new File(_filePath);

        return file.delete();
    }
}
